﻿using OxyPlot;
using OxyPlot.Wpf;
using OxyPlot.Series;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using OxyPlot.Axes;
using System.Collections.Concurrent;
using System.Reflection;

namespace WpfApplication1.ViewModels
{
    public class SmartViewModel
    {
        public Controllers.SmartController smartController { get; set; }
        public Views.NavigationMap navigationMap { get; set; }

        public ICommand exitButton { get; private set; }
        public ICommand pauseModulatingButton { get; private set; }
        public ICommand resetPlotsButton { get; private set; }
        public ICommand resetNavigationFactorsButton { get; private set; }
        public Models.PlotSettings plotSettings { get; private set; }
        public ConcurrentDictionary<String,PlotModel> plotModels { get; private set; }
        public Grid grid { get; set; }


        public SmartViewModel()
        {
            exitButton = new Updater(new Action(closeProgram));
            pauseModulatingButton = new Updater(new Action(pauseModulating));
            resetPlotsButton = new Updater(new Action(resetPlots));
            resetNavigationFactorsButton = new Updater(new Action(resetNavigationFactors));
            plotSettings = new Models.PlotSettings();
            plotModels = new ConcurrentDictionary<String, PlotModel>();
            
            //createa altitude plotmodel
            //altitudePlotModel = new PlotModel("altitude");
            //altitudeLineSeries = new LineSeries("altitude");
            //altitudePlotModel.Series.Add(altitudeLineSeries);
            smartController = new Controllers.SmartController(this);
        }

        public void createPlots()
        {
            setupGrid();
            int plotCounter = 0;
            int rowCounter = 0;
            int colCounter = 0;
            foreach(String key in plotSettings.attributePlotSettings.Keys)
            {
                Boolean[] attributeSettings = (Boolean[])plotSettings.attributePlotSettings[key];
                if (attributeSettings[0])
                {
                    //Create the plot
                    Plot plot = new Plot();
                    //Create the plot model
                    PlotModel plotModel = new PlotModel(key);
                    OxyPlot.Series.LineSeries actualLineSeries = new OxyPlot.Series.LineSeries("actual");
                    actualLineSeries.Color = OxyColor.Parse("#FF0000");//RED
                    plotModel.Series.Add(actualLineSeries);
                    if (attributeSettings[1])
                    {
                        OxyPlot.Series.LineSeries desiredLineSeries = new OxyPlot.Series.LineSeries("desired");
                        desiredLineSeries.Color = OxyColor.Parse("#18A100");//GREEN
                        plotModel.Series.Add(desiredLineSeries);
                    }
                    //add plot model to the hashtable
                    plotModels.TryAdd(key, plotModel);
                    //add plot model to plot
                    plot.Model = plotModel;
                    plotCounter++;

                    Grid.SetColumn(plot, colCounter);
                    Grid.SetRow(plot, rowCounter);
                    grid.Children.Add(plot);

                    //checks when a line break is happening:
                    if (plotCounter % plotSettings.columnCount == 0)
                    {
                        rowCounter++;
                        colCounter = 0;
                        RowDefinition row = new RowDefinition();
                        row.Height = new GridLength(200);
                        grid.RowDefinitions.Add(row);
                    }else{
                        colCounter++;
                    }
                }
            }
        }

        public void setupGrid()
        {
            grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            grid.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            grid.ShowGridLines = true;
            grid.Background = new SolidColorBrush(Colors.LightSteelBlue);

            for (int i = 0; i < plotSettings.columnCount; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition());
            }
            RowDefinition firstRow = new RowDefinition();
            //set possible row height TODO
            firstRow.Height = new GridLength(200);
            grid.RowDefinitions.Add(firstRow);

            //test
            //Plot testPlot = new Plot();
            //PlotModel testPlotModel = new PlotModel("test");
            //OxyPlot.Series.LineSeries testLineSeries = new OxyPlot.Series.LineSeries("test");
            //testPlotModel.Series.Add(testLineSeries);
            //testPlot.Model = testPlotModel;


            //testPlotModel.LegendTitle = "Legend";
            //testPlotModel.LegendOrientation = LegendOrientation.Horizontal;
            //testPlotModel.LegendPlacement = LegendPlacement.Outside;
            //testPlotModel.LegendPosition = LegendPosition.TopRight;
            //testPlotModel.LegendBackground = OxyColor.FromAColor(200, OxyColors.White);
            //testPlotModel.LegendBorder = OxyColors.Black;

            //var dateAxis = new OxyPlot.Axes.DateTimeAxis(AxisPosition.Bottom, "Date", "dd/MM/yy HH:mm") { MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot, IntervalLength = 80 };
            //testPlotModel.Axes.Add(dateAxis);
            //var valueAxis = new OxyPlot.Axes.LinearAxis(AxisPosition.Left, 0) { MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot, Title = "Value" };
            //testPlotModel.Axes.Add(valueAxis);

            //Grid.SetColumn(testPlot,3);
            //Grid.SetRow(testPlot, 0);
            //grid.Children.Add(testPlot);
        }
        public void closeProgram()
        {
            Console.WriteLine("PMR-INFO: Shutting down system.");
            smartController.udpServer.terminateUdpServer();
            Application.Current.Shutdown();
        }
        public void pauseModulating()
        {
            smartController.MODULATING_PAUSED = !smartController.MODULATING_PAUSED;
        }
        public void resetPlots()
        {
            foreach (String key in plotModels.Keys)
            {
                PlotModel plotModel;
                if (plotModels.TryGetValue(key, out plotModel))
                {
                    foreach (OxyPlot.Series.LineSeries lineSerie in plotModel.Series)
                    {
                        switch (lineSerie.Title)
                        {
                            case "actual":
                                lineSerie.Points.Clear();
                                break;
                            case "desired":
                                lineSerie.Points.Clear();
                                break;
                            default:
                                Console.WriteLine("PMR-Error: An illegal LineSeries was found in a Plotmodel");
                                break;
                        }
                    }
                    plotModel.RefreshPlot(true);
                }
            }
        }

        public void resetNavigationFactors()
        {
            smartController.resetNavigationFactors();
        }
        private class Updater : ICommand
        {
            private Action action;

            public Updater(Action action)
            {
                this.action = action;
            }
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
                action();
            }
        }
    }
}
